package vs1;

import Bots.Bots;
import FALCON.FALCON;
import cz.cuni.amis.pogamut.base.utils.guice.AgentScoped;
import cz.cuni.amis.pogamut.ut2004.utils.UT2004BotRunner;
import cz.cuni.amis.utils.exception.PogamutException;

import java.util.Arrays;


@AgentScoped
public class wang_et_al3 extends vs1.wang_et_al2 {

    public static void main(String[] args) throws PogamutException {//主程序
        new UT2004BotRunner(wang_et_al3.class, "Hunter").setMain(true).setConsoleLogging(false).startAgents(agent_num);
        //new UT2004BotRunner(wang_et_al3.class, "Hunter").setMain(true).startAgents(agent_num);
    }

    double st = 1;
    double tt = 0.1; // 0.1

    @Override
    public void FALCONBOT(FALCON[] agent, Bots[] bots) {
        int c = agt;
        if (is_stop(bots[c])) {
            Learning(agent[c], bots[c]);
            bots[c].step++;
            observe(bots[c]);
            bots[c].CurrentStat = Arrays.copyOf(bots[c].stat, bots[c].stat.length);
            int selectedAction;
            if (random.nextDouble() < FALCON.QEpsilon) {                  // 随机行为
                do {
                    SelectVAct(bots[c]);                                  // 和TMP.pert差不多
                    selectedAction = (int) (random.nextDouble() * numAction);
                } while (!bots[agt].vact[selectedAction]);
                bots[c].action = selectedAction;
            } else {
                SelectVAct(bots[c]);                                       // 都差不多

                int s = Teacher_Selection(agent, bots);                       // 通过一个算法选择教师
                double Cp;                                               // 计算一个随机选择率
                if (bots[s].Si == 0 || bots[s].KD == 0) Cp = 0;
                else Cp = 1 - (bots[c].KD / bots[s].KD);
                if (s != c && agent[c].I_Function(bots[c].CurrentStat, bots[c].vact) < st && random.nextDouble() < Cp) { // 如果教师不为自己 且 自己的结果不够确信 且 小于随机选择率
                    //System.out.println("?");
                    bots[c].TF_num += 1;                                     // 转移
                    bots[c].action = agent[s].sPolicy(bots[c].CurrentStat, bots[c].vact); // 由教师智能体选择动作
                } else {                                                    // 否则
                    bots[c].action = agent[c].sPolicy(bots[c].CurrentStat, bots[c].vact); // 由智能体自己选择动作
                }
            }
            bots[c].r = 0;
            bots[c].lastheal = info.getHealth() / 100.0;
            bots[c].hitdamage = 0;
            DoAct(bots[c], bots[c].action);
        }
    }


    /////////////////////////////////////////////////////////////////
    /////////////////////// 多智能体部分  ///////////////////////////
    ////////////////////////////////////////////////////////////////
    public synchronized int Teacher_Selection(FALCON[] agent, Bots[] bots) {   // 教师选择算法
        int c = agt;                                                                 //
        int s = c;
        double maxSC = 0;

        double Qvalue = agent[c].Q_Function(bots[c].CurrentStat, bots[c].vact);       // 计算Q值

        if (Qvalue > bots[c].Qbest) bots[c].Qbest = Qvalue;                               // 计算历史Qbest

        if (bots[c].Qbest != 0) bots[c].Si = Qvalue / bots[c].Qbest;
        else bots[c].Si = 0; // Si为   Q/Qbest

        double KDbest = 0;                                                          // 平均最好击杀
        for (int w = 0; w < agent_num; w++) {
            if (bots[w].KD > KDbest) KDbest = bots[w].KD;
        } // 如果谁的击杀最多为平均最好击杀

        if (KDbest == 0) bots[c].EI = 0;
        else bots[c].EI = bots[c].KD / KDbest;                                   // Ei为击杀情况


        for (int v = 0; v < agent_num; v++) {
            if (v != c) {                                                               // 除了本智能体
                Qvalue = agent[v].Q_Function(bots[c].CurrentStat, bots[c].vact);
                if (Qvalue > bots[v].Qbest) bots[v].Qbest = Qvalue;                       // 更新其他智能体的Qbest
                if (bots[v].Qbest != 0) bots[v].Si = Qvalue / bots[v].Qbest;
                else bots[v].Si = 0; //本Si值

                if (KDbest == 0) bots[v].EI = 0;
                else bots[v].EI = bots[v].KD / KDbest;                             // 本EI值

                if (agent[v].I_Function(bots[c].CurrentStat, bots[c].vact) > tt && bots[v].EI > bots[c].EI) { // 如果教师智能体够明确 且 表现更好
                    bots[v].Sc = bots[v].EI;                           // 利用Sc值找到最好的
                    if (bots[v].Sc > maxSC) {
                        maxSC = bots[v].Sc;
                        s = v;
                    }
                }
            }
        }
        return s;
    }


}